const Redis = require('ioredis');
const config = require('../config');
const { logger } = require('../utils/logger');

class CacheService {
  /**
   * 构造函数
   * @constructor
   */
  constructor() {
    this.redis = new Redis({
      host: config.redis.host,
      port: config.redis.port,
      password: config.redis.password,
      retryStrategy: (times) => {
        const delay = Math.min(times * 50, 2000);
        return delay;
      }
    });

    this.redis.on('error', (error) => {
      logger.error('Redis connection error:', error);
    });

    this.redis.on('connect', () => {
      logger.info('Redis connected successfully');
    });
  }

  /**
   * 获取缓存值
   * @param {string} key - 缓存键
   * @returns {Promise<Object>} - 缓存值
   */
  async get(key) {
    try {
      const value = await this.redis.get(key);
      return value ? JSON.parse(value) : null;
    } catch (error) {
      logger.error('Cache get error:', error);
      return null;
    }
  }

  /**
   * 设置缓存值
   * @param {string} key - 缓存键
   * @param {Object} value - 缓存值
   * @param {number} ttl - 过期时间（秒），默认为3600秒
   * @returns {Promise<boolean>} - 设置结果
   */
  async set(key, value, ttl = 3600) {
    try {
      const stringValue = JSON.stringify(value);
      if (ttl) {
        await this.redis.setex(key, ttl, stringValue);
      } else {
        await this.redis.set(key, stringValue);
      }
      return true;
    } catch (error) {
      logger.error('Cache set error:', error);
      return false;
    }
  }

  /**
   * 删除缓存值
   * @param {string} key - 缓存键
   * @returns {Promise<boolean>} - 删除结果
   */
  async del(key) {
    try {
      await this.redis.del(key);
      return true;
    } catch (error) {
      logger.error('Cache delete error:', error);
      return false;
    }
  }

  /**
   * 检查缓存键是否存在
   * @param {string} key - 缓存键
   * @returns {Promise<boolean>} - 检查结果
   */
  async exists(key) {
    try {
      return await this.redis.exists(key);
    } catch (error) {
      logger.error('Cache exists error:', error);
      return false;
    }
  }

  /**
   * 增加缓存值
   * @param {string} key - 缓存键
   * @returns {Promise<number>} - 增加后的值
   */
  async incr(key) {
    try {
      return await this.redis.incr(key);
    } catch (error) {
      logger.error('Cache increment error:', error);
      return null;
    }
  }

  /**
   * 减少缓存值
   * @param {string} key - 缓存键
   * @returns {Promise<number>} - 减少后的值
   */
  async decr(key) {
    try {
      return await this.redis.decr(key);
    } catch (error) {
      logger.error('Cache decrement error:', error);
      return null;
    }
  }

  /**
   * 获取哈希表中的值
   * @param {string} hash - 哈希表键
   * @param {string} key - 哈希表中的键
   * @returns {Promise<Object>} - 哈希表中的值
   */
  async hget(hash, key) {
    try {
      const value = await this.redis.hget(hash, key);
      return value ? JSON.parse(value) : null;
    } catch (error) {
      logger.error('Cache hash get error:', error);
      return null;
    }
  }

  /**
   * 设置哈希表中的值
   * @param {string} hash - 哈希表键
   * @param {string} key - 哈希表中的键
   * @param {Object} value - 哈希表中的值
   * @returns {Promise<boolean>} - 设置结果
   */
  async hset(hash, key, value) {
    try {
      const stringValue = JSON.stringify(value);
      await this.redis.hset(hash, key, stringValue);
      return true;
    } catch (error) {
      logger.error('Cache hash set error:', error);
      return false;
    }
  }

  /**
   * 删除哈希表中的值
   * @param {string} hash - 哈希表键
   * @param {string} key - 哈希表中的键
   * @returns {Promise<boolean>} - 删除结果
   */
  async hdel(hash, key) {
    try {
      await this.redis.hdel(hash, key);
      return true;
    } catch (error) {
      logger.error('Cache hash delete error:', error);
      return false;
    }
  }

  /**
   * 设置缓存过期时间
   * @param {string} key - 缓存键
   * @param {number} ttl - 过期时间（秒）
   * @returns {Promise<boolean>} - 设置结果
   */
  async expire(key, ttl) {
    try {
      await this.redis.expire(key, ttl);
      return true;
    } catch (error) {
      logger.error('Cache expire error:', error);
      return false;
    }
  }

  /**
   * 清空缓存
   * @returns {Promise<boolean>} - 清空结果
   */
  async clear() {
    try {
      await this.redis.flushall();
      return true;
    } catch (error) {
      logger.error('Cache clear error:', error);
      return false;
    }
  }

  /**
   * 获取Redis客户端
   * @returns {Redis} - Redis客户端
   */
  getClient() {
    return this.redis;
  }
}

module.exports = new CacheService(); 